package com.yutou.droid.UselessCode;

import android.app.Application;
import android.os.Build;
import android.os.Handler;

import com.yutou.droid.UselessCode.Utils.ProxyClass;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

/**
 * hook工具，劫持Activity过程
 */
public class HookUtils {
    private static HookUtils hook=null;
    private Application application;
    public static HookUtils init(Application application){
        if(hook==null){
            hook=new HookUtils();
            hook.application=application;
        }
        return hook;
    }

    /**
     * Hook掉Activity的启动过程，用ProxyClass来监听启动过程
     * @throws Exception
     */
    public void hookActivity() throws Exception {
        System.out.println("===============开始处理Activity============");
        //获取ActivityManagerNative类；
        Class activityManagerNative=Class.forName("android.app.ActivityManager");
        if(Build.VERSION.SDK_INT<Build.VERSION_CODES.LOLLIPOP){ //低版本Android的类都不同
            activityManagerNative=Class.forName("android.app.ActivityManagerNative");
        }
        //获取IActivityManagerSingleton的IActivityManagerSingleton变量
        String fieldName="IActivityManagerSingleton";
        if(Build.VERSION.SDK_INT<Build.VERSION_CODES.O){ //低版本Android的变量名不同
            fieldName="gDefault";
        }
        Field getDefault=activityManagerNative.getDeclaredField(fieldName);
        getDefault.setAccessible(true);
        Object value=getDefault.get(null);
        //获取Singleton
        Class singleton=Class.forName("android.util.Singleton");
        Field singField=singleton.getDeclaredField("mInstance");
        singField.setAccessible(true);
        //获取IActivityManager
        Object activityManager=singField.get(value);
        Class iActivityManager=Class.forName("android.app.IActivityManager");
        ProxyClass proxyClass=new ProxyClass(activityManager,application);
        Object proxy= Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{iActivityManager},proxyClass);
        singField.set(value,proxy);
        System.out.println("===============处理结束============");
    }
    /**
     * Hook拿到ActivityThread的mH变量
     */
    public  void hookHandle() {
        try {
            System.out.println("===============开始处理Handle============");
            Class activityThreadClass = Class.forName("android.app.ActivityThread");
            Field activityThreadField = activityThreadClass.getDeclaredField("sCurrentActivityThread");
            activityThreadField.setAccessible(true);
            Object activityThread = activityThreadField.get(null);

            Field mHField = activityThreadClass.getDeclaredField("mH");
            mHField.setAccessible(true);
            Handler mH = (Handler) mHField.get(activityThread);
            Field mCallbackField = Handler.class.getDeclaredField("mCallback");
            mCallbackField.setAccessible(true);
            mCallbackField.set(mH, new MyHandlerCallback(mH));
            System.out.println("===============Handle处理结束============");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
